﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml;


using ParamSetCollection.General.ParamTable;
using ParamSetCollection.General.Parameters.Normal;

namespace ParamSetCollection.General.Parameters.Alarms
{
    public delegate void OnAlarmStateChangeEventHandler(AlarmUnit au);

    public class AlarmsHelper
    {

        #region============================== 变量 ====================================
        public event OnAlarmStateChangeEventHandler OnAlarmStateChange;

        public ushort[] RDataZone = null;

        private int m_EnHeadAddr = 2;
        private int m_ReadHeadAddr = 3;
        private int m_LevelHeadAddr = 4;
        private int m_ActionAddr = 4;

        private string m_code = "Alarm";
        private string m_configPath = System.Environment.CurrentDirectory + "\\Config\\Alarms\\";

        public Dictionary<string, AlarmUnit> AlarmsDic = new Dictionary<string, AlarmUnit>();
        public List<AlarmUnit> AlarmList = new List<AlarmUnit>();//报警单元列表

        #endregion=====================================================================


        #region============================== 属性 ====================================
        #endregion=====================================================================


        #region============================= 内部函数 ================================
        private void ReadConfig()
        {
            if(File.Exists(m_configPath)==true)
            {
                try
                {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(m_configPath);

                    XmlNode mainNode = doc.SelectSingleNode("Alarms");
                    if(mainNode!=null)
                    {
                        for (int i = 0; i < mainNode.ChildNodes.Count; i++)
                        {
                            AlarmUnit au = AlarmUnit.GetAlarmUnit(mainNode.ChildNodes[i], AlarmList.Count);
                            AlarmsDic.Add(au.ErrorCode, au);
                            AlarmList.Add(au);

                            au.OnStateChange += Au_OnStateChange;
                        }
                    }

                }
                catch (Exception)
                {

                    //异常记录
                }
            }

        }

    
        #endregion====================================================================


        #region============================= 保护函数 ================================
        #endregion====================================================================


        #region============================= 公开函数 ================================
        public AlarmsHelper()
        {

        }

        public AlarmsHelper(AlarmInfo info,string machineType, ushort[] dataBuf)
        {
            RDataZone = dataBuf;

            m_configPath = m_configPath + machineType + "Alarms.cfg";

            ReadConfig();
        }

        public void ReadXML(string path)
        {
            m_configPath = path;

            if (File.Exists(m_configPath) == false)
                return;

            try
            {
                XmlDocument doc= new XmlDocument();
                doc.Load(m_configPath);
                XmlNode mainNode = doc.SelectSingleNode("Alarms");
                if(mainNode!=null )
                {
                    for (int i = 0; i < mainNode.ChildNodes.Count; i++)
                    {
                        XmlNode aNode= mainNode.ChildNodes[i];
                        AlarmUnit au = AlarmUnit.GetAlarmUnit(aNode, AlarmList.Count);

                        AlarmList.Add(au);
                        AlarmsDic.Add(au.ErrorCode, au);
                    }
                }
            }
            catch (Exception ex)
            {

                
            }


        }

        public void SetAddr(int enHead,int readHead,int actHead)
        {
            m_EnHeadAddr = enHead;
            m_ReadHeadAddr = readHead;
            m_ActionAddr = actHead;

        }

        public void BindingCommData(List<CommDataUnit> source)
        {
            int j = 0;
            for (int i = 0; i < AlarmList.Count; i++)
            {
                int _bitIndex = i % 16;

                AlarmList[i].InputBindingStateData(source[m_ReadHeadAddr + j - CommDataUnit.AddrHead], _bitIndex);
                if (_bitIndex == 15)
                    j++;

            }
        }


        public void RenewData()
        {
            List<ushort> temp = new List<ushort>();
            //判断控制字的个数
            int count = (int)Math.Ceiling((double)this.AlarmList.Count / 16);
            for (int i = 0; i < count; i++)
            {
                temp.Add(RDataZone[m_ReadHeadAddr + i]);
            }

            //数据状态分派到各单元
            for (int i = 0; i < temp.Count; i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    if ((16 * i + j) >= AlarmList.Count)
                    {
                        break;
                    }

                    ushort _temp = 0;

                    _temp = (ushort)temp[i];

                    bool state = Convert.ToBoolean(Convert.ToInt32(((_temp << (15 - j)) & 0xffff) >> 15));
                    if (state)
                    {

                    }
                    AlarmList[16 * i + j].Activated = state;
                }
            }
        }
        #endregion====================================================================


        #region============================= 消息响应 ================================
        private void Au_OnStateChange(AlarmUnit au)
        {
            OnAlarmStateChange?.Invoke(au);
        }



        #endregion====================================================================


    }
}
